package ui;

import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**This class is JavaFx Alert Builder
 *Use example:
 *    Optional<ButtonType> btn =  new DialogUtils(new DialogUtils.Builder()).showAndWait();
 * @author LIANG
 * @since version 1.0 2020-11
*/
public class DialogUtils {

    private static Alert alert;
    private HBox contentPane;

    public DialogUtils(Builder builder){
        alert = new Alert(builder.type);
        alert.setTitle(builder.title);
        Stage stage = (Stage)alert.getDialogPane().getScene().getWindow();
        if(builder.iconPath != null)
            stage.getIcons().add(new Image(builder.iconPath));
        else
            stage.getIcons().add(new Image(getClass().getResourceAsStream(getIcoPath(builder.type))));
        alert.setHeaderText(builder.headerText);
        alert.setContentText(builder.content);
        if(builder.setButtonTypes.size()>0){
            alert.getButtonTypes().setAll(builder.setButtonTypes);
        }
        if(builder.addButtonTypes.size()>0){
            alert.getButtonTypes().addAll(builder.addButtonTypes);
        }
        if(builder.contentElements.size()>0){
            contentPane = new HBox();
            contentPane.setAlignment(Pos.TOP_RIGHT);
            contentPane.getChildren().setAll(builder.contentElements);
            alert.getDialogPane().setContent(contentPane);
        }
    }

    public Optional<ButtonType> showAndWait(){
        return alert.showAndWait();
    }
    public void show(){
        alert.show();
    }
    public HBox getContentPane(){ return contentPane; }
    public Node getNode(Node node){
        int index = contentPane.getChildren().indexOf(node);
        return contentPane.getChildren().get(index);
    }
    public Node getNode(String nodeId){
        return contentPane.lookup(nodeId);
    }
    /**Dialog Builder
     * @author LIANG
     * @version 1.0 2020-11
     */
    public static class Builder{
        private String title;
        private String headerText;
        private String content;
        private String iconPath;
        private Alert.AlertType type;
        private List<ButtonType> setButtonTypes = new ArrayList<>();
        private List<ButtonType> addButtonTypes = new ArrayList<>();
        private List<Node> contentElements = new ArrayList<>();
        /**This method allows you to set the Dialogs title Text
         * @param title title
         */
        public Builder setTitle(String title){
            this.title = title;
            return this;
        }
        /**This method allows you to set the Dialogs content Text
         * @param content content
         */
        public Builder setContent(String content){
            this.content = content;
            return this;
        }
        /**This method allows you to set the Dialogs header Text
         * @param headerText headerText
         */
        public Builder setHeadText(String headerText){
            this.headerText = headerText;
            return this;
        }
        /**This method allows you to set the Dialogs iconPath to replace the default icons define by the Alert.AlertType
         * @param iconPath iconPath
         */
        public Builder setIconPath(String iconPath){
            this.iconPath = iconPath;
            return this;
        }
        /**initialize the default icon by AlertType
         * @param alertType alertType
         */
        public Builder setAlertType(Alert.AlertType alertType){
            this.type = alertType;
            return this;
        }
        /**set Dialog Buttons use List<ButtonType>
         * this will clear all default buttons
         * @param buttonTypes buttonTypes
         */
        public Builder setButtonTypes(List<ButtonType> buttonTypes){
            this.setButtonTypes = new ArrayList<>(buttonTypes);
            return this;
        }
        /**set Dialog Buttons use ButtonType[]
         * this will clear all default buttons
         * @param buttonTypes buttonTypes
         */
        public Builder setButtonTypes(ButtonType... buttonTypes){
            this.setButtonTypes = new ArrayList<>(Arrays.asList(buttonTypes));
            return this;
        }
        /**add Buttons to Dialog use List<ButtonType>
         * this will NOT clear default buttons
         * @param buttonTypes buttonTypes
         */
        public Builder addButtonTypes(List<ButtonType> buttonTypes){
            this.addButtonTypes = new ArrayList<>(buttonTypes);
            return this;
        }
        /**add Buttons to Dialog use ButtonType[]
         * this will NOT clear default buttons
         * @param buttonTypes buttonTypes
         */
        public Builder addButtonTypes(ButtonType... buttonTypes){
            this.addButtonTypes = new ArrayList<>(Arrays.asList(buttonTypes));
            return this;
        }
        /**set Dialog custom Node use List<Node>
         * this will clear all dialog's child
         * @param contentElements contentElements
         */
        public Builder setContentElements(List<Node> contentElements){
            this.contentElements = new ArrayList<>(contentElements);
            return this;
        }
        /**set Dialog Buttons use Node[]
         * this will clear all dialog's child
         * @param contentElements contentElements
         */
        public Builder setContentElements(Node... contentElements){
            this.contentElements = new ArrayList<>(Arrays.asList(contentElements));
            return this;
        }
    }


    /**Set the Dialog's AlertType & ICON
     * if you want to change The default sets of icon img,YOU CAN
     * @see Builder setIconPath()
     */
    private static String getIcoPath(Alert.AlertType type){
        String path = "/img/dialog/dialog.png";
        String ALERT = "/img/dialog/alert.png";
        String INFORMATION = "/img/dialog/information.png";
        String CONFIRMATION = "/img/dialog/confirmation.png";
        String ERROR = "/img/dialog/error.png";
        switch (type){
            case NONE:
                break;
            case WARNING:
                path = ALERT;
                break;
            case INFORMATION:
                path = INFORMATION;
                break;
            case ERROR:
                path = ERROR;
                break;
            case CONFIRMATION:
                path = CONFIRMATION;
                break;
        }
        return path;
    }
}
